package com.qingsong.component;

import com.qingsong.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.qingsong.result.Result;
import com.qingsong.result.ResultCode;

/**
 * 异常处理类，用于统一处理控制器中的异常
 * @author qingsong
 */

@RestControllerAdvice(basePackages = {"com.qingsong"})
public class ExceptionAdvice {

    /**
     * 日志记录器
     */
    private static final Logger log = LoggerFactory.getLogger(ExceptionAdvice.class);

    /**
     * 处理业务异常 ServiceException
     * @param e ServiceException 实例
     * @return 包含错误信息的 Result 对象
     */
    @ExceptionHandler(ServiceException.class)
    public Object serviceException(ServiceException e) {
        log.error("业务异常: " + e.getMessage());
        return new Result<>(ResultCode.FAILED, e.getMessage());
    }

    /**
     * 处理方法参数验证失败的异常 MethodArgumentNotValidException
     * @param e MethodArgumentNotValidException 实例
     * @return 包含错误信息的 Result 对象
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object methodArgumentNotValidException(Exception e) {
        //获取BindingResult
        BindingResult bindingResult;
        if (e instanceof MethodArgumentNotValidException) {
            bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
        } else {
            bindingResult = ((BindException) e).getBindingResult();
        }
        // 获取BindingResult中所有属性错误信息集合中的第一个属性错误
        FieldError firstFieldError = bindingResult.getFieldErrors().get(0);
        // 异常信息："xxx实例的xxx属性校验失败: xxx异常信息"
        String message = String.format("%s实例的%s属性校验失败: %s",
                firstFieldError.getObjectName(),
                firstFieldError.getField(),
                firstFieldError.getDefaultMessage());
        // 记录日志
        log.error(message);
        // 响应
        return new Result<>(ResultCode.VALIDATE_FAILED, message);
    }

    /**
     * 处理其他所有异常
     * @param e 异常实例
     * @return 包含错误信息的 Result 对象
     */
    @ExceptionHandler(Exception.class)
    public Object exception(Exception e) {
        log.error("其他异常: " + e.getMessage());
        return new Result<>(ResultCode.FAILED, e.getMessage());
    }
}